<?php

namespace app\privatearea\controller\astro\v1;

use app\astrologer\controller\Upload;
use app\common\cachemodel\privatearea\PrivateAreaAstro;
use app\common\cachemodel\ZhunleAstrWithdrawalRecord;
use app\common\lib\Util;
use app\privatearea\controller\AstroAuth;
use think\Db;
use think\Env;
use think\response\Json;

class Earnings extends AstroAuth
{
    protected $startDay = 5;
    protected $endDay = 20;

    /**
     * 钱包-收益明细
     * @return Json
     */
    public function list()
    {
        $page = input('page/d', 1);
        $limit = input('limit/d', 10);

        $astrId = $this->astro['id'];
        $pageData = Db::table('wechat_backup_07_18_14_43_00.private_area_astr_account_record')->alias('r')
            ->join('wechat_backup_07_18_14_43_00.private_area_goods g', 'r.gid=g.id')
            ->join('wechat_backup_07_18_14_43_00.private_area_question_info q', 'r.qid=q.id')
            ->where(['r.astr_id' => $astrId, 'r.type' => 1])->order('r.create_time desc')
            ->field('g.name,q.hash,r.create_time,r.good_amount,r.proportion')
            ->paginate(['page' => $page, 'list_rows' => $limit])->toArray();
        $dataList = [];
        foreach ($pageData['data'] as $datum)
        {
            $price = sprintf('%.2f', $datum['good_amount'] * $datum['proportion']);

            $dataList[] = [
                'left_info' => [
                    'title_left' => '任务编号：',
                    'title_copy' => $datum['hash'],
                    'des_center' => $datum['name'],
                    'des_bottom' => date('Y-m-d H:i:s', $datum['create_time']),
                    'des_status_bottom' => '完成任务',
                ],
                'right_info' => [
                    'des_type' => '私域',
                    'des_price' => $price . '元',
                ],
                'target' => 'local',
                'link' => 'empty',
            ];
        }
        $pageData['data'] = $dataList;
        $pageData['header_info'] = $this->getWithdrawalHeaderInfo($this->astro['id']);

        return show(config('code.success'), '请求成功', $pageData);
    }

    /**
     * 结算历史(无分页)
     * @return Json
     */
    public function getWithdrawalList()
    {
        $resData = Db::table('wechat_backup_07_18_14_43_00.private_astr_withdrawal_record')
            ->where(['astr_id' => $this->astro['id']])
            ->order('id desc')
            ->column("date,astr_earnings,percent,income_tax,after_tax_income,withdrawal_time,is_withdrawal,excluding_earning", 'id');

        $withdrawalList = [];
        foreach ($resData as $datum)
        {
            if ($datum['date'] < 20240101)
            {   // 当前只显示已打款数据
                $itemData = [
                    'status_des' => '已打款',
                    'status' => $datum['is_withdrawal'] == 1 ? 1 : 0,
                    'des_list' => [
                        '结算月份：' . date('Y-m月', strtotime($datum['date'])),
                        '结算金额：¥' . $datum['astr_earnings'],
                        '扣除个税金额：¥' . $datum['income_tax'],
                        '实际到账：¥' . $datum['after_tax_income'],
                    ],
                ];
            } else
            {   // 当前只显示已打款数据
                $itemData = [
                    'status_des' => $datum['is_withdrawal'] == 1 ? '已打款' : '',
                    'status' => $datum['is_withdrawal'] == 1 ? 1 : 0,
                    'des_list' => [
                        '结算月份：' . date('Y-m月', strtotime($datum['date'])),
                        '结算总金额：¥' . ($datum['astr_earnings'] - $datum['excluding_earning']),
                    ],
                ];
            }
            $withdrawalList[] = $itemData;
        }

        return show(config('code.success'), '请求成功', [
            'withdrawal_list' => $withdrawalList,
            'header_info' => $this->getWithdrawalHeaderInfo($this->astro['id']),
        ]);
    }

    public function getWithdrawalHeaderInfo(int $astrId, int $type = 1)
    {
        $data = Db::table('wechat_backup_07_18_14_43_00.private_astr_withdrawal_record')
            ->where(['date' => ['>', 20231201], 'astr_id' => $astrId, 'is_withdrawal' => 0])
            ->field('sum(astr_earnings) as earnings,sum(excluding_earning) as excluding_earning')->find();
        $earnings = $data['earnings'] ?? 0;
        $excludingEarning = $data['excluding_earning'] ?? 0;
        // 获取当前 已申请 提现金额
        $withdrawalInfo = Db::table('wechat_backup_07_18_14_43_00.zhunle_astr_withdrawal_record')->where(['type' => 2, 'astr_id' => $astrId, 'check_status' => ['in', [0, 1]], 'is_remit' => 0])->field('withdrawal_amount,check_status,id,invoice_url')->find();
        $withdrawal = $withdrawalInfo['withdrawal_amount'] ?? 0; // 已申请提现
        $withdrawaAmount = $earnings - $excludingEarning - $withdrawal;   // 可提现总金额 - 扣除金额 - 已申请提现 = 剩余可提现金额
        $withdrawaAmount = max($withdrawaAmount, 0);
        if ($type === 1)
        {
            $zhunleAstrId = (new PrivateAreaAstro())->getZhunleAstrIdById($astrId);
            return [
                'title' => "可提现金额：{$withdrawaAmount}元",
                'hint' => '展示的金额为税前收益，每月初结算后可在规定时间申请提现',
                'des' => '',
                'detail_list' => [],
                'withdraw_hint' => $zhunleAstrId ? '请前往准了咨询师端提现，检测到你在准了咨询师可能有其它收益需要合并结算，感谢配合。' : '',
            ];
        } else
        {
            return [
                'balance' => $withdrawaAmount,    // 剩余可提现金额
                'withdrawal_amount' => $withdrawal,   // 当前提现金额
                'check_status' => (int)($withdrawalInfo['check_status'] ?? 0), // 提现审核状态 0:待审核 1:审核通过
                'wid' => (int)($withdrawalInfo['id'] ?? 0),
                'invoice_url' => $withdrawalInfo['invoice_url'] ?? '',
            ];
        }
    }

    /**
     * 提现列表
     * @return Json
     */
    public function getWithdrawHistoryList()
    {
        $page = input('page/d', 1);
        $limit = input('limit/d', 10);

        $pageData = (new ZhunleAstrWithdrawalRecord())->where(['type' => 2, 'astr_id' => $this->astro['id']])
            ->order('id desc')
            ->paginate(['page' => $page, 'list_rows' => $limit])->toArray();

        $dataList = [];
        foreach ($pageData['data'] as $itemData)
        {
            $desList = [
                [
                    'title' => '申请提现金额：',
                    'des_info' => [
                        'content' => $itemData['withdrawal_amount'] . '元',
                        'color' => '#24252A',
                    ],
                ], [
                    'title' => '申请日期：',
                    'des_info' => [
                        'content' => date('Y年m月d日 H:i', $itemData['create_time']),
                        'color' => '#24252A',
                    ],
                ], [
                    'title' => '扣除个税金额：',
                    'des_info' => [
                        'content' => $itemData['income_tax'] . '元',
                        'color' => '#24252A',
                    ],
                ], [
                    'title' => '实际到账金额：',
                    'des_info' => [
                        'content' => $itemData['after_tax_income'] . '元',
                        'color' => '#24252A',
                    ],
                ],
            ];

            if ($itemData['is_remit'] == 1)
            {
                $desList[] = [
                    'title' => '打款时间：',
                    'des_info' => [
                        'content' => date('Y年m月d日 H:i', $itemData['remit_time']),
                        'color' => '#24252A',
                    ],
                ];
            }

            switch ($itemData['check_status'])
            {
                case 1: // 审核通过
                    if ($itemData['is_remit'] == 1)
                    {
                        $desList[] = [
                            'title' => '当前状态：',
                            'des_info' => [
                                'content' => '已打款',
                                'color' => '#00D8D3',
                            ],
                        ];
                    } else
                    {
                        $desList[] = [
                            'title' => '当前状态：',
                            'des_info' => [
                                'content' => '审核已通过等待打款中',
                                'color' => '#00D8D3',
                            ],
                        ];
                    }
                    break;
                case 2: // 审核未通过
                    $desList[] = [
                        'title' => '当前状态：',
                        'des_info' => [
                            'content' => '审核不通过',
                            'color' => '#FFB500',
                        ],
                    ];
                    $desList[] = [
                        'title' => '原因：',
                        'des_info' => [
                            'content' => $itemData['check_remark'],
                            'color' => '#24252A',
                        ],
                    ];
                    break;
                case 3: // 已取消
                    $desList[] = [
                        'title' => '当前状态：',
                        'des_info' => [
                            'content' => '申请已取消',
                            'color' => '#9FA1AA',
                        ],
                    ];
                    break;
                default: // 等待审核
                    $desList[] = [
                        'title' => '当前状态：',
                        'des_info' => [
                            'content' => '等待审核',
                            'color' => '#FFB500',
                        ],
                    ];
            }

            $dataList[] = [
                'invoice_url' => Env::get('host.domain') . '/web/agreement/astrologer_app_invoice_view.html?pdf_url=' . base64_encode(Upload::getOssPrivateUrl($itemData['invoice_url'])),
                'des_list' => $desList,
            ];
        }

        $pageData['data'] = $dataList;

        $pageData['header_info'] = $this->getWithdrawalHeaderInfo($this->astro['id']);

        return show(config('code.success'), '请求成功', $pageData);
    }

    /**
     * 申请提现信息
     * @return Json
     */
    public function getApplyWithdrawInfo()
    {
        $headerInfo = $this->getWithdrawalHeaderInfo($this->astro['id'], 2);

        $rightBtnInfo = ['is_show' => 0, 'title' => '', 'target' => '', 'link' => '',];
        $cancelBtnInfo = ['is_show' => 0, 'title' => '', 'id' => 0,];
        if ($headerInfo['withdrawal_amount'] > 0)
        {   // 当前已有 申请提现 记录
            $rightBtnInfo = [
                'is_show' => 1,
                'title' => '查看发票',
                'target' => 'link',
                'link' => Env::get('host.domain') . '/web/agreement/astrologer_app_invoice_view.html?pdf_url=' . base64_encode(Upload::getOssPrivateUrl($headerInfo['invoice_url'])),
            ];
            $invoiceAmount = $headerInfo['balance'];
            if ($headerInfo['check_status'] == 1)
            {   // 审核通过
                $bottomBtnInfo = [
                    'is_show' => 1,
                    'title' => '审核通过等待打款中',
                    'is_apply_withdraw' => 0,
                ];
            } else
            {   // 待审核
                $bottomBtnInfo = [
                    'is_show' => 1,
                    'title' => '等待审核中',
                    'is_apply_withdraw' => 0,
                ];
                $cancelBtnInfo = [
                    'is_show' => 1,
                    'title' => '取消申请',
                    'id' => $headerInfo['wid'],
                ];
            }
        } else
        {   // 没有提现记录
            $day = (int)date('d');
            if ($headerInfo['balance'] >= 100 && $day >= $this->startDay && $day <= $this->endDay)
            {
                $rightBtnInfo = [
                    'is_show' => 1,
                    'title' => '上传发票',
                    'target' => 'local',
                    'link' => 'upload',
                ];
                $bottomBtnInfo = [
                    'is_show' => 1,
                    'title' => '申请提交',
                    'is_apply_withdraw' => 1,
                ];
            } else
            {
                if ($day < $this->startDay || $day > $this->endDay)
                {
                    $bottomBtnInfo = [
                        'is_show' => 1,
                        'title' => '未到提现日暂不支持提现',
                        'is_apply_withdraw' => 0,
                    ];
                }
                if ($headerInfo['balance'] < 100)
                {
                    $bottomBtnInfo = [
                        'is_show' => 1,
                        'title' => '提现金额不可少于100元',
                        'is_apply_withdraw' => 0,
                    ];
                }
            }
            $invoiceAmount = $headerInfo['balance'];
        }

        $title = "可提现金额：{$headerInfo['balance']}元";
        if ($headerInfo['withdrawal_amount'] > 0)
        {   // 已申请 提现
            $title .= $headerInfo['check_status'] == 1 ? "\r\n审核通过等待打款金额：{$headerInfo['withdrawal_amount']}元" : "\r\n正在审核提现金额：{$headerInfo['withdrawal_amount']}元";
        }

        $resData = [
            'title' => $title,
            'right_btn_info' => $rightBtnInfo,
            'des_center' => $headerInfo['withdrawal_amount'] > 0 ? '' : "开票金额：{$invoiceAmount}元",
            'invoice_des' => $headerInfo['withdrawal_amount'] > 0 ? '' : "名称：北京星座女神文化传媒有限公司\r\n税号：9111 0105 3181 9744 80\r\n地址电话：北京市朝阳区高碑店乡金家村中街8号C-3009  010-85164828",
            'des_bottom' => "提现金额需要上传对应金额的发票才可提现；每月{$this->startDay}-{$this->endDay}日可提交提现申请，请务必阅读并理解下方信息。",
            'bottom_btn_info' => $bottomBtnInfo ?? null,
            'cancel_btn_info' => $cancelBtnInfo,
            'url_help' => Env::get('host.domain') . '/web/agreement/astrologer_withdraw_guide.html',
        ];

        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 申请/取消申请提现
     * @return Json
     */
    public function applyWithdraw()
    {
        $type = input('type/d', 0);
        $invoiceUrl = input('invoice_url/s', '');
        $id = input('id/d', 0);
        // 开票 信息
        $purchaserName = '北京星座女神文化传媒有限公司';
        $purchaserRegisterNum = '911101053181974480';

        if (!in_array($type, [0, 1], true))
        {
            return show(config('code.error'), '请求异常，请稍后重试');
        }

        if (Util::commentCheck($this->astro['id'], ['applyWithdraw', 'type' => $type, 'invoiceUrl' => $invoiceUrl, 'id' => $id], 5))
        {
            return show(config('code.error'), '操作频繁，请稍后再试～');
        }

        if ($type === 1)
        {   // 申请 开票
            if ((new ZhunleAstrWithdrawalRecord())->where(['astr_id' => $this->astro['id'], 'type' => 2, 'is_remit' => 0, 'check_status' => ['in', [0, 1]]])->count())
            {
                return show(config('code.error'), '正在申请提现中，操作失败');
            }
            if (empty($invoiceUrl))
            {
                return show(config('code.error'), '请上传发票');
            }
            $day = (int)date('d');
            if ($day < $this->startDay || $day > $this->endDay)
            {   // 未到提现日期
                return show(config('code.error'), '未到提现日暂不支持提现');
            }
            $zhunleAstrId = (new PrivateAreaAstro())->getZhunleAstrIdById($this->astro['id']);
            if ($zhunleAstrId)
            {
                return show(config('code.error'), '请前往准了咨询师端提现，检测到你在准了咨询师可能有其它收益需要合并结算，感谢配合。');
            }
            $list = [];
            $totalWithdrawalAmount = 0;
            // 共 可提现 金额
            $privateWithdrawalAmount = Db::table('wechat_backup_07_18_14_43_00.private_astr_withdrawal_record')
                ->where(['astr_id' => $this->astro['id'], 'wid' => 0, 'is_withdrawal' => 0, 'date' => ['>', 20231201]])
                ->field('astr_earnings,excluding_earning,id,date')->select();
            foreach ($privateWithdrawalAmount as $datum)
            {   // 累加 私域 可提现金额 - 私域扣减金额
                $totalWithdrawalAmount = $totalWithdrawalAmount + $datum['astr_earnings'] - $datum['excluding_earning'];
                $list['siyu'][] = [
                    'id' => (int)$datum['id'],
                    'date' => (int)$datum['date'],
                    'des' => date('Y年m月', strtotime($datum['date'])),
                ];
            }

            if ($totalWithdrawalAmount < 100)
            {
                return show(config('code.error'), '当前可提现金额不足100，请联系客服');
            }

            if (Env::get('host.name') === 'online')
            {   // 线上才进行校验
                $res = Util::aliInvoiceOcr($invoiceUrl);
                if ($res['code'] != 200)
                {
                    return show(config('code.error'), '发票识别失败，请重新上传');
                }
                if ($res['data']['amountInFiguers'] < $totalWithdrawalAmount)
                {
                    return show(config('code.error'), '发票金额不足可提现金额，请重新上传');
                }
                if ($res['data']['purchaserRegisterNum'] !== $purchaserRegisterNum)
                {
                    return show(config('code.error'), '发票购买方信息错误，请重新上传');
                }
                if ($res['data']['purchaserName'] !== $purchaserName)
                {
                    return show(config('code.error'), '发票购买方信息错误，请重新上传');
                }
                // $res['data']['amountInFiguers']          含税金额
                // $res['data']['invoiceCode']              发票代码
                // $res['data']['invoiceNum']               发票号码
                // $res['data']['invoiceDate']              开票日期 格式YYYYMMDD
                // $res['data']['checkCode']                校验码 【注意：专票、全电票可不传，其他必填。校验码支持全位和后6位】
                // $res['data']['totalAmount']              不含税金额 【注意：普票可不传，其他发票必填 。全电票请传含税金额，其他发票需传 不含税金额】

                // $res['data']['purchaserRegisterNum']     购买方 纳税人识别号
                // $res['data']['purchaserName']            购买方 公司名称
                if (in_array($res['data']['invoiceType'], ['电子发票(普通发票)', '电子发票(专用发票)'], true))
                {   // 全电发票 全电票请传含税金额
                    $bhsje = $res['data']['amountInFiguers'];
                } else
                {   // 不含税金额
                    $bhsje = $res['data']['totalAmount'];
                }
                /**
                 * 发票 查验
                 * @param string $fpdm 发票代码 【注意：全电票可不传，其他必传】
                 * @param string $fphm 发票号码
                 * @param string $kprq 开票日期 格式YYYYMMDD
                 * @param string $xym 校验码 【注意：专票、全电票可不传，其他必填。校验码支持全位和后6位】
                 * @param string $bhsje 不含税金额 【注意：普票可不传，其他发票必填 。全电票请传含税金额，其他发票需传 不含税金额】
                 * @return array
                 */
                $checkRes = Util::aliIinvoiceCheck($res['data']['invoiceCode'], $res['data']['invoiceNum'], $res['data']['invoiceDate'], $res['data']['checkCode'], $bhsje);
                if ($checkRes['code'] != 200 || $checkRes['data']['result'] != 1)
                {
                    return show(config('code.error'), '发票识别失败，请重新上传');
                }
                if ($checkRes['data']['info']['buyerTaxNo'] !== $purchaserRegisterNum)
                {
                    return show(config('code.error'), '发票购买方信息错误，请重新上传');
                }
                if ($checkRes['data']['info']['buyerName'] !== $purchaserName)
                {
                    return show(config('code.error'), '发票购买方信息错误，请重新上传');
                }
                if ($checkRes['data']['info']['totalAmount'] < $totalWithdrawalAmount)
                {
                    return show(config('code.error'), '发票金额不足可提现金额，请重新上传');
                }
            }
            $incomeTax = Util::CalculationTaxRate($totalWithdrawalAmount);
            $nowTime = time();
            $astrWithdrawalData = [
                'astr_id' => $this->astro['id'],
                'type' => 2,
                'withdrawal_amount' => $totalWithdrawalAmount,  // 提现金额
                'income_tax' => $incomeTax,
                'after_tax_income' => $totalWithdrawalAmount - $incomeTax,
                'invoice_url' => $invoiceUrl,
                'invoice_check_data' => json_encode($checkRes ?? [], JSON_UNESCAPED_UNICODE), // 发票查验数据
                'list' => json_encode($list, JSON_UNESCAPED_UNICODE),   // 流水来源
                'create_time' => $nowTime,
                'create_date' => date('Ym', $nowTime),
            ];

            $id = (new ZhunleAstrWithdrawalRecord())->SaveData($astrWithdrawalData);

            if ($id)
            {
                return show(config('code.success'), '申请提现成功');
            } else
            {
                return show(config('code.error'), '服务异常，请稍后再试');
            }
        } else
        {   // 取消 申请开票
            if (!$id)
            {
                return show(config('code.error'), '请求异常，请稍后重试');
            }

            try
            {
                $data = (new ZhunleAstrWithdrawalRecord())->where(['id' => $id, 'type' => 2, 'astr_id' => $this->astro['id']])->findOrFail()->toArray();
                if ($data['check_status'] == 3)
                {
                    return show(config('code.error'), '已经取消了，请勿重复操作');
                }
                if ($data['is_remit'])
                {
                    return show(config('code.error'), '提现申请状态异常，操作失败');
                }
                if ($data['check_status'] == 1)
                {
                    return show(config('code.error'), '已通过审核，无法取消');
                }
                if ($data['check_status'] == 2)
                {
                    return show(config('code.error'), '审核未通过，已经自动取消了');
                }

                (new ZhunleAstrWithdrawalRecord())->where(['id' => $id])->update(['check_status' => 3, 'check_time' => $this->request->time()]);

                return show(config('code.success'), '提现申请取消成功');
            }
            catch (\Exception $e)
            {
                return show(config('code.error'), '服务异常，请稍后重试');
            }
        }
    }
}
